package com.alageek.personalblog.web;

import com.alageek.personalblog.common.constant.BlogConstant;
import com.alageek.personalblog.entity.doo.Clazz;
import com.alageek.personalblog.entity.doo.Label;
import com.alageek.personalblog.entity.doo.Post;
import com.alageek.personalblog.entity.query.PostQuery;
import com.alageek.personalblog.entity.vo.PostVo;
import com.alageek.personalblog.service.ClazzService;
import com.alageek.personalblog.service.LabelService;
import com.alageek.personalblog.service.PostService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Date;
import java.util.List;

/**
 * 博文管理控制器
 * @author AlaGeek
 */
@Slf4j
@Controller
@RequestMapping("/admin/blog")
public class AdminBlogController {

    private final PostService postService;
    private final ClazzService clazzService;
    private final LabelService labelService;

    public AdminBlogController(PostService postService, ClazzService clazzService, LabelService labelService) {
        this.postService = postService;
        this.clazzService = clazzService;
        this.labelService = labelService;
    }

    @GetMapping("/list")
    public String list(
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            ModelMap modelMap) {
        List<Clazz> clazzList = clazzService.findAllSortByIdDesc();
        if (pageNum > 0 && pageSize > 0) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<PostVo> postList = postService.findByParamWithClazz(new PostQuery());
        modelMap.addAttribute(BlogConstant.ATTR_NAME_CLAZZ_LIST, clazzList);
        modelMap.addAttribute(BlogConstant.ATTR_NAME_POST_LIST, new PageInfo<PostVo>(postList));
        return "admin/blog-list";
    }

    @PostMapping("/search")
    public String search(
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            PostQuery postQuery,
            ModelMap modelMap) {
        if (pageNum > 0 && pageSize > 0) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<PostVo> postList = postService.findByParamWithClazz(postQuery);
        modelMap.addAttribute(BlogConstant.ATTR_NAME_POST_LIST, new PageInfo<PostVo>(postList));
        return "admin/blog-list :: blogList";
    }

    @GetMapping("/add")
    public String add(ModelMap modelMap) {
        PostQuery postQuery = new PostQuery();
        postQuery.setMark(1);
        postQuery.setRecommendStatus(true);
        postQuery.setRewardStatus(true);
        postQuery.setCopyrightStatus(true);
        postQuery.setCommentStatus(true);
        fillModelMapByPostQuery(modelMap, postQuery);
        return "admin/blog-add";
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/add")
    public String doAdd(PostQuery postQuery, ModelMap modelMap, RedirectAttributes attributes) {
        log.debug("Add post: {}", postQuery);
        // 参数校验
        if (postQuery.getTitle() == null || postQuery.getTitle().trim().length() == 0) {
            fillModelMapByPostQuery(modelMap, postQuery);
            modelMap.addAttribute(BlogConstant.ATTR_NAME_MESSAGE, "文章标题不能为空");
            return "admin/blog-add";
        }
        // 文章标题判重
        Post repeatPost = new Post();
        repeatPost.setTitle(postQuery.getTitle());
        List<Post> repeatPostList = postService.findByParam(repeatPost);
        if (repeatPostList != null && repeatPostList.size() > 0 && repeatPostList.get(0) != null) {
            fillModelMapByPostQuery(modelMap, postQuery);
            modelMap.addAttribute(BlogConstant.ATTR_NAME_MESSAGE, "文章标题不能重复");
            return "admin/blog-add";
        }
        // 新增文章
        Post post = new Post(postQuery);
        post.setCreateTime(new Date());
        post.setUpdateTime(post.getCreateTime());
        int savePostResult = postService.saveSelective(post);
        log.debug("post: {}", post);
        if (savePostResult == 1) {
            // 新增文章成功
            log.debug("Add post success");
            // 新增分类关系
            if (postQuery.getClazzIds() != null) {
                String[] clazzIds = postQuery.getClazzIds().split(",");
                for (String tmp : clazzIds) {
                    Integer clazzId = Integer.valueOf(tmp);
                    int result = clazzService.savePostClazzRelationship(post.getId(), clazzId);
                    log.debug("PostClazzRelationship: postId:{}, clazzId:{}, result:{}", post.getId(), clazzId, result);
                }
            }
            // 新增标签关系
            if (postQuery.getLabelIds() != null) {
                String[] labelIds = postQuery.getLabelIds().split(",");
                for (String tmp : labelIds) {
                    Integer labelId = Integer.valueOf(tmp);
                    int result = labelService.savePostLabelRelationship(post.getId(), labelId);
                    log.debug("PostClazzRelationship: postId:{}, clazzId:{}, result:{}", post.getId(), labelId, result);
                }
            }
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "新增成功");
        } else {
            // 新增文章失败
            log.debug("Add post fail");
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "新增失败");
        }
        return "redirect:/admin/blog/list";
    }

    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Integer id, ModelMap modelMap, RedirectAttributes attributes) {
        Post post = postService.findById(id);
        if (post == null) {
            attributes.addAttribute(BlogConstant.ATTR_NAME_MESSAGE, "没有该文章，无法编辑");
            return "redirect:/admin/blog/list";
        } else {
            PostQuery postQuery = new PostQuery(post);
            List<Integer> clazzIdList = clazzService.findClazzIdsByPostId(post.getId());
            List<Integer> labelIdList = labelService.findLabelIdsByPostId(post.getId());
            postQuery.setClazzIds(listToString(clazzIdList));
            postQuery.setLabelIds(listToString(labelIdList));
            fillModelMapByPostQuery(modelMap, postQuery);
            return "admin/blog-edit";
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/edit")
    public String doEdit(PostQuery postQuery, ModelMap modelMap, RedirectAttributes attributes) {
        log.debug("Edit post: {}", postQuery);
        // 参数校验
        if (postQuery.getTitle() == null || postQuery.getTitle().trim().length() == 0) {
            fillModelMapByPostQuery(modelMap, postQuery);
            modelMap.addAttribute(BlogConstant.ATTR_NAME_MESSAGE, "文章标题不能为空");
            return "admin/blog-edit";
        }
        // 文章标题判重
        Post repeatPost = new Post();
        repeatPost.setTitle(postQuery.getTitle());
        List<Post> repeatPostList = postService.findByParam(repeatPost);
        if (repeatPostList != null && repeatPostList.size() > 0) {
            for (Post tmp : repeatPostList) {
                if(!tmp.getId().equals(postQuery.getId())){
                    fillModelMapByPostQuery(modelMap, postQuery);
                    modelMap.addAttribute(BlogConstant.ATTR_NAME_MESSAGE, "文章标题不能重复");
                    return "admin/blog-edit";
                }
            }
        }
        // 编辑文章
        Post post = new Post(postQuery);
        post.setUpdateTime(post.getCreateTime());
        int editPostResult = postService.modifyByIdSelective(post);
        log.debug("post: {}", post);
        if (editPostResult == 1) {
            // 编辑文章成功
            log.debug("Edit post success");
            // 删除分类关系
            int removeClazzIdsResult = clazzService.removeClazzIdsByPostId(post.getId());
            log.debug("removeClazzIdsResult: {}", removeClazzIdsResult);
            // 删除标签关系
            int removeLabelIdsResult = labelService.removeLabelIdsByPostId(post.getId());
            log.debug("removeLabelIdsResult: {}", removeLabelIdsResult);
            // 编辑分类关系
            if (postQuery.getClazzIds() != null) {
                String[] clazzIds = postQuery.getClazzIds().split(",");
                for (String tmp : clazzIds) {
                    Integer clazzId = Integer.valueOf(tmp);
                    int result = clazzService.savePostClazzRelationship(post.getId(), clazzId);
                    log.debug("PostClazzRelationship: postId:{}, clazzId:{}, result:{}", post.getId(), clazzId, result);
                }
            }
            // 编辑标签关系
            if (postQuery.getLabelIds() != null) {
                String[] labelIds = postQuery.getLabelIds().split(",");
                for (String tmp : labelIds) {
                    Integer labelId = Integer.valueOf(tmp);
                    int result = labelService.savePostLabelRelationship(post.getId(), labelId);
                    log.debug("PostClazzRelationship: postId:{}, clazzId:{}, result:{}", post.getId(), labelId, result);
                }
            }
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "编辑成功");
        } else {
            // 编辑文章失败
            log.debug("Edit post fail");
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "编辑失败");
        }
        return "redirect:/admin/blog/list";
    }

    @Transactional(rollbackFor = Exception.class)
    @GetMapping("/delete/{id}")
    public String delete(@PathVariable("id") Integer id, RedirectAttributes attributes) {
        // 删除
        int removePostResult = postService.removeById(id);
        if (removePostResult == 1) {
            // 删除成功
            log.debug("Edit post success");
            // 删除分类关系
            int removeClazzIdsResult = clazzService.removeClazzIdsByPostId(id);
            log.debug("removeClazzIdsResult: {}", removeClazzIdsResult);
            // 删除标签关系
            int removeLabelIdsResult = labelService.removeLabelIdsByPostId(id);
            log.debug("removeLabelIdsResult: {}", removeLabelIdsResult);
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "删除成功");
        } else {
            // 删除失败
            log.debug("Edit post fail");
            attributes.addFlashAttribute(BlogConstant.ATTR_NAME_MESSAGE, "删除失败");
        }
        return "redirect:/admin/blog/list";
    }

    private void fillModelMapByPostQuery(ModelMap modelMap, PostQuery postQuery) {
        List<Clazz> clazzList = clazzService.findAllSortByIdDesc();
        List<Label> labelList = labelService.findAllSortByIdDesc();
        modelMap.addAttribute(BlogConstant.ATTR_NAME_POST, postQuery);
        modelMap.addAttribute(BlogConstant.ATTR_NAME_CLAZZ_LIST, clazzList);
        modelMap.addAttribute(BlogConstant.ATTR_NAME_LABEL_LIST, labelList);
    }

    private String listToString(List<Integer> list){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<list.size();i++){
            stringBuilder.append(list.get(i));
            if(i<list.size()-1){
                stringBuilder.append(",");
            }
        }
        return stringBuilder.toString();
    }

}
